package com.acmedcare.framework.exchange.center.executer.job;

import com.acmedcare.framework.exchange.center.entity.bean.Task;
import com.acmedcare.framework.exchange.center.entity.bean.TaskDetail;
import com.acmedcare.framework.exchange.center.entity.dto.ActionCommand;
import com.acmedcare.framework.exchange.center.entity.dto.TaskCommandEvent;
import com.acmedcare.framework.exchange.center.entity.dto.TaskDetailCommandEvent;
import com.acmedcare.framework.exchange.center.executer.ExecutorConfig;
import com.acmedcare.framework.exchange.center.executer.ProcessInfo;
import com.acmedcare.framework.exchange.center.executer.ProcessMonitor;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BaseJob {

  protected List<String> paths = new ArrayList<>();

  protected String resolveJarPath(String path) {

    // todo resolve jar
    paths.add(path);
    return path;
  }

  public void executeShell(String bashCommand, TaskDetail taskDetail, int timeOut) {

    Runtime runtime = Runtime.getRuntime();
    StringBuilder sb = new StringBuilder();
    taskDetail.setStatus(true);
    Process process = null;
    try {
      process = runtime.exec(bashCommand);
      ProcessInfo processInfo = ProcessInfo
          .builder()
          .time(timeOut)
          .process(process)
          .startTime(new Date())
          .taskDetail(taskDetail)
          .build();

      ProcessMonitor.addProcess(processInfo);
      int status = process.waitFor();
      if (status != 0) {
        taskDetail.setStatus(false);
        sb.append("execute command fail,command:" + bashCommand);
      }

      BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
      StringBuffer stringBuffer = new StringBuffer();
      String line;
      while ((line = br.readLine()) != null) {
        stringBuffer.append(line).append("\n");
      }

      sb.append("\n");
      sb.append(stringBuffer.toString());

    } catch (Exception e) {

      if (process != null && process.isAlive()) {

        process.destroyForcibly();
      }

      taskDetail.setStatus(false);
      //如果被monitor 强制停止则获取停止日志
      if (taskDetail.getExecuteLog() != null) {

        sb.append(taskDetail.getExecuteLog()).append("\n");
      }

      sb.append("execute command fail,command:" + bashCommand + e.getMessage());
    }

    taskDetail.setExecuteLog(sb.toString());
  }

  protected void clearJar() {

    if (!paths.isEmpty()) {

      // todo delete path
    }
  }

  protected void publishDetail(TaskDetail taskDetail) {

    TaskDetailCommandEvent detailCommandEvent = new TaskDetailCommandEvent();
    detailCommandEvent.setActionCommand(ActionCommand.Add);
    detailCommandEvent.setData(taskDetail);
    ExecutorConfig.getInstance().getAcmedcareEventPublisher()
        .publishEvent(ExecutorConfig.EXCHANGENAME, detailCommandEvent);
  }

  protected void publishTask(Task task) {
    TaskCommandEvent commandEvent = new TaskCommandEvent();
    commandEvent.setData(task);
    commandEvent.setActionCommand(ActionCommand.Update);
    ExecutorConfig.getInstance().getAcmedcareEventPublisher()
        .publishEvent(ExecutorConfig.EXCHANGENAME, commandEvent);

  }
}
